<?php
$this_dir = dirname(__FILE__) . '/';
require_once $this_dir . '../plugin/autoload.php';

$uri = $_SERVER['REQUEST_URI'];

function route($uri)
{
    $rules = ConfLib::get('route', 'controller');
    foreach ($rules as $k=>$v) {
        if (1 === preg_match('/' . $k . '/', $uri)) {
            if (isset($v[strtolower($_SERVER['REQUEST_METHOD'])])) {
                return $v[strtolower($_SERVER['REQUEST_METHOD'])];
            }
            throw new HttpException('', 405);
        }
    }
    $rules = ConfLib::get('route', 'jump');
    foreach ($rules as $v) {
        if (1 === preg_match('/' . $v . '/', $uri)) {
            throw new HttpException(
                '', 301,
                array(
                    'http' => array(
                        'uri' => $uri . '/',
                    ),
                )
            );
        }
    }

    /*todo 这里throw，不知道content-type，对api输出404 html页面是不对的，
    怎么解决？不对吗？也许是对的，404的时候不需要关心content-type。
    是否说明不应该在本域做ajax api，全部使用外域jsonp open api？
    那本域输出atom时仍然有404问题。
    */
    throw new HttpException('', 404);
}
try {
    $tmp = route($uri);
    $tmp2 = explode('->', $tmp);
    $controller_name = $tmp2[0];
    $action_name = $tmp2[1];
    $c = new $controller_name ($uri);
    $r = $c->$action_name ();
} catch (HttpException $e) {
    $r = $e->getData();
}

function getStatusStr($code)
{
    //fastcgi与apache module不同
    //这里按照fastcgi格式
    //http://cn.php.net/manual/en/function.header.php
    $http_code_map = array(
        '200' => '200 OK',
        '202' => '202 Accepted',
        '301' => '301 Moved Permanently',
        '302' => '302 Found',
        '400' => '400 Bad Request',
        '404' => '404 Not Found',
    );
    return 'Status: ' . $http_code_map[$code];
}

function output($r)
{
    //fastcgi与apache module不同
    //这里按照fastcgi格式
    //http://cn.php.net/manual/en/function.header.php
    $status_str = getStatusStr($r['http']['status_code']);
    if (in_array($r['http']['status_code'], array(301, 302, 500))) {
        header('Location: ' . $r['http']['uri'], true, $r['http']['status_code']);
        exit;
    } else {
        header($status_str);
    }
    $tmp = array();
    foreach ($r['http']['cache-control'] as $k=>$v) {
        if (is_numeric($k) && in_array($v, array('private', 'public', 'no-cache'))) {
            $tmp[] = $v;
            continue;
        }
        if ($k == 'max-age') {
            $tmp[] = 'max-age=' . $v;
            continue;
        }
    }
    header('Cache-Control:' . implode(', ', $tmp));
    if (isset($r['http']['cache-control']['max-age'])) {
        header(
            'Expires:' . gmdate(
                'D, d M Y H:i:s T', 
                time() + $r['http']['cache-control']['max-age']
            )
        );
    }

    $v = $r['data'];
    header('Content-Type: ' . $r['http']['content-type']);
    switch($r['http']['content-type']) {
    case 'application/x-bittorrent' :
            header('Content-disposition: attachment; filename='.basename($v['filename']));
            header("Content-Transfer-Encoding: binary");
            //header('Content-Length: ' . strlen($v['torrent']));
            echo $v['torrent'];
            break;
    case 'text/html' :
        $v['static_uri'] = ConfLib::get('static', 'uri');
        require dirname(__FILE__) . '/../view/default/'. $r['tpl'] . '.tpl';
        break;
    case 'text/plain' :
        echo $v;
        break;
    case 'application/json' :
        echo json_encode($v);
        break;
    case 'application/atom+xml' :
        //todo
        break;
    }
    return true;
}
output($r);
exit;
?>
